﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using HeritageAcademy.Models.DataModels;
using HeritageAcademy.Models.Loaders;

namespace HeritageAcademy.Models.ViewModels
{
    public class ResultsViewModel : INotifyPropertyChanged
    {
        #region Parameters

        string _testId = String.Empty;
        string _userId = String.Empty;
        TestDataLoader _testDataLoader; // load test data
        TestResultsLoader _testResultsLoader; // load test results
        Dictionary<string, string> _enigma; // right answers dict
        
        private ObservableCollection<ResultViewModel> _results;
        private int _ra, _wa;

        #endregion

        #region Ctor

        public ResultsViewModel(string userId, string testId)
        {
            _userId = userId;
            _testId = testId;
            _results = new ObservableCollection<ResultViewModel>();
        }

        #endregion

        #region Properties

        public ObservableCollection<ResultViewModel> Results
        {
            get { return _results ?? (_results = new ObservableCollection<ResultViewModel>()); }
            set 
            { 
                _results = value;
                OnPropertyChanged("Results");
            }
        }

        public int NumberOfRightAnswers
        {
            get { return _ra; }
            set 
            { 
                _ra = value;
                OnPropertyChanged("NumberOfRightAnswers");
            }
        }

        public int NumberOfWrongAnswers
        {
            get { return _wa; }
            set 
            { 
                _wa = value;
                OnPropertyChanged("NumberOfWrongAnswers");
            }
        }

        public int TotalNumberOfAnswers
        {
            get { return _wa+_ra; }
        }
        
        public string TestId
        {
            get { return _testId; }
            set { _testId = value; }
        }

        public string UserId
        {
            get { return _userId; }
            set { _userId = value; }
        }

        #endregion

        #region Public Methods

        public void InitializeResults(string testDataFilePath)
        {
            _testDataLoader = new TestDataLoader(new TestWizard(), testDataFilePath);
            _enigma = new Dictionary<string, string>();

            _ra = 0;
            _wa = 0;
            
            if (_testDataLoader.Model.Id == _testId)
                foreach (var page in _testDataLoader.Model.TestPage)
                    _enigma.Add(page.Id, page.Code);
        }

        public void GetTestResults()
        {
            _testResultsLoader = new TestResultsLoader(new TestResults(), _userId);

            _results.Clear();
            foreach (var result in _testResultsLoader.Model.Results)
            {
                if (result.Id != _testId) continue;
                foreach (var page in result.Pages)
                {
                    var pageStatus = true;
                    var status = pageStatus;
                    foreach (var answer in page.Answers.Where(answer => status))
                    {
                        if (answer.Status == "false")
                        {
                            foreach (var ans in SeparateString(_enigma[page.Id], "|"))
                                if (answer.Id == ans) pageStatus = false;
                        }
                        else
                        {
                            pageStatus = false;
                            foreach (var ans in SeparateString(_enigma[page.Id], "|"))
                                if (answer.Id == ans) pageStatus = true;
                        }
                    }

                    var data = new ResultViewModel {PageNumber = page.Id, Time = page.Time};
                    if (pageStatus)
                    {
                        data.Status = "верно";
                        ++_ra;
                    }
                    else
                    {
                        data.Status = "не верно";
                        ++_wa;
                    }
                    _results.Add(data);
                }
            }
        }

        /// <summary>
        /// Convert (separate) input string into test and answer id's.
        /// </summary>
        /// <param name="inputString">Input string</param>
        /// <param name="delimiter">Delimiter</param>
        /// <returns>string[0] - test id; string[1] - answer id</returns>
        static IEnumerable<string> SeparateString(string inputString, string delimiter)
        {
            var separator = Convert.ToChar(delimiter);
            return inputString.Split(separator);
        }

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        void OnPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }

    public class ResultViewModel
    {
        public string PageNumber { get; set; }
        public string Time { get; set; }
        public string Status { get; set; }
    }
}
